// 为了和 extern/rtos/private/xthread_local.hpp 接口保持一致，对于拥有 thread_local 实现的平台也需要使用此接口
//
// 注意:
// struct type{
//      type(int xx){}
//      ...
// };
//
// // 假如当前类型没有无参构造函数，那么下面不带参数的版本将会导致编译错误
// xthread_local(foo, type);
// 
// // 使用 xthread_local_new + type 所需的参数列表
// xthread_local(foo, type) = xthread_local_new(10);
#ifndef xpack_macro_xthread_local
#define xpack_macro_xthread_local
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::macro_xthread_local::inc
#include"configure/switch.hpp"
#include"macro/xalign.hpp"
#include"macro/xnew.hpp"
#include"meta/has_constructor.hpp"
#include"meta/remove_const.hpp"
#include"meta/remove_ptr.hpp"
#include"meta/remove_volatile.hpp"
#pragma pop_macro("xuser")

#if xuse_mixc_rtos
    #include"extern/rtos/private/xthread_local.hpp"
#else
    namespace mixc::macro_xthread_local{
        template<class lambda_t, class object_t>
        concept is_valid_lambda = requires(lambda_t lambda, object_t * ptr){
            lambda(ptr);
        };

        template<class object_t>
        struct wrapper_core{
        private:
            xalign(alignof(object_t))
            u08 m_item[sizeof(object_t)];

            using origin_t = inc::remove_volatile<inc::remove_const<object_t>>;

            typedef struct core{
                object_t m_item; // m_item 可能是数组，无法直接调用析构函数
                core(auto ... args) : m_item(args...){}
            } * corep;

        public:
            template<class lambda_t>
            requires(is_valid_lambda<lambda_t, origin_t>)
            wrapper_core(lambda_t && lambda){
                lambda((origin_t *)m_item);
            }

            template<class ... args_t>
        #if xfor_vscode_hint
            requires(sizeof...(args_t) == 0)
        #else
            requires(sizeof...(args_t) == 0 and inc::has_constructor<origin_t, void()>)
        #endif
            wrapper_core(args_t ...){
                init(m_item);
            }

            object_t & operator *() const {
                return *(object_t *)this;
            }

            object_t * operator->() const {
                return (object_t *)(this);
            }

            operator object_t *() const {
                return (object_t *)(this);
            }

        protected:
            static void init(auto mem, auto ... args){
                xnew(mem) object_t(args...);
            }
            ~wrapper_core(){
                corep(this)->~core();
            }
        };

        template<class object_t>
        struct wrapper : wrapper_core<object_t>{
            using base_t = wrapper_core<object_t>;
            using base_t::base_t;
            using base_t::operator *;
            using base_t::operator->;
        };
    }

    #define xthread_local(NAME,...)         inline thread_local ::mixc::macro_xthread_local::wrapper<__VA_ARGS__> NAME
    #define xthread_local_new(...)                                                                  \
        [](auto * object) {                                                                         \
            using __object_t = ::mixc::macro_xthread_local::inc::remove_ptr<decltype(object)>;      \
            xnew(object) __object_t{__VA_ARGS__};                                                   \
        }

#endif
#endif